﻿package com.chinaway.mobile.balance.impl;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.chinaway.handler.MobileHandler;
import com.chinaway.mobile.authcode.AuthCodeDiscern;
import com.chinaway.mobile.authcode.AuthCodeDiscernSdimpl;
import com.chinaway.mobile.balance.MobileBalance;
import com.chinaway.mobile.http.util.ClientOperate;
import com.chinaway.mobile.model.Account;
import com.chinaway.mobile.model.QueryBill;
import com.chinaway.proxy.Proxy;
import com.chinaway.proxy.ProxyService;

public class MobileBalanceSdImpl implements MobileBalance {
	private final static Logger log = LoggerFactory
			.getLogger(MobileBalanceSdImpl.class);
	public String mobilekey = "sdmobile";
	private static final int REQUEST_TIMEOUT = 5 * 1000; // 设置请求超时10秒钟
	private static final int SO_TIMEOUT = 5 * 1000; // 设置等待数据超时时间10秒钟
	private static String randCodeURL = "https://sd.ac.10086.cn/portal/login/briefValidateCode.jsp?random=3";
	private static String shanDongLoginURL = "https://sd.ac.10086.cn/portal/servlet/LoginServlet";// https://sd.ac.10086.cn/portal/servlet/LoginServlet
	private static String cookieServletURL = "http://www.sd.10086.cn/portal/servlet/CookieServlet?FieldID=2";
	private static String firstLogin = "http://www.sd.10086.cn/eMobile/firstLogin_commit.action";
	private static String qryBalanceResult = "http://www.sd.10086.cn/eMobile/qryBalance_result.action?menuid=qryBalance&pageid=";
	private static String  gprs="http://www.sd.10086.cn/eMobile/index_qryprivilege.action?menuid=index&pageid=";

	private static String loginAttritdUrl = "https://sd.ac.10086.cn/eMobile/loginSSO.action?Attritd=";
	@SuppressWarnings("unused")
	private static String emobileHeader = "https://sd.ac.10086.cn/emall/eMobile/emobileHeader.action";

	// 查询短彩信费、上网费、代收费、费用合计
	private static String queryBill = "http://www.sd.10086.cn/eMobile/queryBill_custInfo.action?pageid=";
	private static String queryBillDetail = "http://www.sd.10086.cn/eMobile/queryBill_billInfo.action?pageid=";

	@SuppressWarnings("unused")
	private static String GBK = "GBK";
	private static String UTF = "UTF-8";
	private HttpResponse response;
	private HttpEntity entity;
	private DefaultHttpClient httpclient = null;
	private CookieStore cookieStore = null;

	private HttpContext localContext = null;
	private ClientOperate co = new ClientOperate();

	private AuthCodeDiscern authCodeDiscern = new AuthCodeDiscernSdimpl();

	protected ProxyService proxyService;

	public void setProxyService(ProxyService proxyService) {
		this.proxyService = proxyService;
	}

	public MobileBalanceSdImpl(ProxyService proxyService) {
		this.proxyService = proxyService;
	}

	public MobileBalanceSdImpl() {
	}

	String date = "";
	public int accountCount = 0;

	public int getAccountCount() {
		return accountCount;
	}

	public void setAccountCount(int accountCount) {
		this.accountCount = accountCount;
	}

	// 创建对象池
	@Override
	public Account account(String mobile, String password, String date, Proxy px) {
		accountCount++;

		if (accountCount >= 4) {
			Account account = new Account(mobile, password);

			String returnArr = "";
			try {
				returnArr = queryAgain();

			} catch (UnsupportedEncodingException e) {
				log.info("the last queryAgain失败" + "message:" + e.toString()
						+ ",Method=" + e.getStackTrace()[0].getMethodName()
						+ ",Line=" + e.getStackTrace()[0].getLineNumber());
			}
			if (returnArr.contains("话费余额")) {
				log.info(" the last queryAgain successed! mobile:" + mobile);
				account.setSuccess(Account.SUCCESS);
				account.setBalance(StringUtils.substringBetween(returnArr,
						"[\"话费余额\",\"", "元\"]"));

				log.info("手机卡:" + mobile + "密码:" + password + "余额:"
						+ account.getBalance() + "套餐外费用:" + account.getChit()
						+ "增值业务费" + account.getValueAdded() + "代收费:"
						+ account.getCharge() + "本月费用合计:" + account.getTotal()
						+ " message：" + account.getMessage() + "是否成功："
						+ account.getSuccess());

			} else {
				log.info(mobile + ":第" + --accountCount + "次查询余额失败！");
				account.setCode(3333);
				account.setSuccess(Account.FAIL);
				log.info("第" + --accountCount + "次查询余额失败！" + "代理ip："
						+ px.getIp() + ":" + px.getPort() + "手机卡:" + mobile
						+ "密码:" + password + "余额:" + account.getBalance()
						+ "套餐外费用:" + account.getChit() + "增值业务费"
						+ account.getValueAdded() + "代收费:"
						+ account.getCharge() + "本月费用合计:" + account.getTotal()
						+ " message：" + account.getMessage() + "是否成功："
						+ account.getSuccess());
			}
			return account;
		}

		this.date = date;
		if (mobile.length() != 11) {
			return new Account(mobile, password, 11, Account.FAIL, "手机号码位数不正确");
		}
		if (password.length() != 6) {
			return new Account(mobile, password, 11, Account.FAIL, "服务密码位数不正确");
		}
		// 设置代理ip
		HttpParams httpParams = new BasicHttpParams();
//		HttpHost proxy = new HttpHost(px.getIp(), px.getPort(), "http");

		// 设置超时时间
		HttpConnectionParams.setConnectionTimeout(httpParams, REQUEST_TIMEOUT);
		HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
		// 设置代理
//		ConnRouteParams.setDefaultProxy(httpParams, proxy);
		// log.info("代理ip：" + px.getIp() + ":" + px.getPort() + ",mobile:"
		// + mobile);

		httpclient = new DefaultHttpClient();
		httpclient = (DefaultHttpClient) wrapClient(httpclient);
		httpclient.setParams(httpParams);
		cookieStore = new BasicCookieStore();
		localContext = new BasicHttpContext();

		httpclient.getParams().setParameter(
				ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
		// 设置cookie的兼容性，这一行必须要加，否则服务器无法获取登陆状态
		HttpClientParams.setCookiePolicy(httpclient.getParams(),
				CookiePolicy.BROWSER_COMPATIBILITY);
		localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

		// 获取wtptc cookie
		// String wt=co.getWTFPC();
		// Cookie cwt=new BasicClientCookie("WT-FPC", wt);
		// cookieStore.addCookie(cwt);

		Cookie ccm = new BasicClientCookie("CmProvid", "sd");
		cookieStore.addCookie(ccm);

		// 访问主页,获取pool——80 Cookie
		// String index="http://www.sd.10086.cn";
		// index = co.getText("访问主页 80cook",httpclient, localContext, index);

		Account account = login(mobile, password, px);

		HttpPost httpost = null;
		if (account.getCode() == 0) {

			try {
				String pageid = Math.random() + "";
				httpost = new HttpPost(queryBill + pageid);

				Header accept = new BasicHeader("Accept",
						"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
				Header lan = new BasicHeader("Accept-Language",
						"zh-CN,zh;q=0.8");
				Header headerconn = new BasicHeader("Connection", "keep-alive");
				Header caco = new BasicHeader("Cache-Control", "max-age=0");
				Header origin = new BasicHeader("Origin",
						"http://www.sd.10086.cn");
				Header headerref = new BasicHeader("Referer",
						"http://www.sd.10086.cn/eMobile/queryBill.action?menuid=queryBill&pageId="
								+ Math.random() + "");
				Header headerhost = new BasicHeader("Host", "www.sd.10086.cn");
				Header contype = new BasicHeader("Content-Type",
						"application/x-www-form-urlencoded");

				httpost.addHeader(contype);
				httpost.addHeader(headerhost);
				httpost.addHeader(origin);
				httpost.addHeader(headerconn);
				httpost.addHeader(headerref);
				httpost.addHeader(accept);
				httpost.addHeader(caco);
				httpost.addHeader(lan);
				List<NameValuePair> nvps = new ArrayList<NameValuePair>();
				nvps.add(new BasicNameValuePair("menuid", "queryBill"));
				nvps.add(new BasicNameValuePair("fieldErrFlag", ""));
				nvps.add(new BasicNameValuePair("contextPath", "/eMobile"));
				nvps.add(new BasicNameValuePair("customInfo.custName", ""));
				nvps.add(new BasicNameValuePair("customInfo.brandName", ""));
				nvps.add(new BasicNameValuePair("customInfo.prodName", ""));
				nvps.add(new BasicNameValuePair("customInfo.subsId", ""));
				nvps.add(new BasicNameValuePair("cycleStartDate", ""));
				nvps.add(new BasicNameValuePair("retMonth", ""));
				nvps.add(new BasicNameValuePair("month", this.date));
				httpost.setEntity(new UrlEncodedFormEntity(nvps, UTF));

				response = httpclient.execute(httpost, localContext);

				entity = response.getEntity();
				if (entity != null) {
					StringEntity my_entity = new StringEntity(
							EntityUtils.toString(entity), "utf-8");
					String contentText = EntityUtils.toString(my_entity);
					QueryBill qb = new QueryBill();
					qb.setCustName(StringUtils.substringBetween(contentText,
							"name=\"customInfo.custName\" value=\"", "\"")
							.replaceAll("amp;", ""));
					qb.setAcctId(StringUtils.substringBetween(contentText,
							"name=\"cycleMap.acctId_" + this.date, "\" id")
							.substring(11));
					qb.setBrandName(StringUtils.substringBetween(contentText,
							"name=\"customInfo.brandName\" value=\"", "\""));
					qb.setCycle(StringUtils.substringBetween(contentText,
							"name=\"cycleMap.cycle_" + this.date, "\" id")
							.substring(11));
					qb.setCycleStartDate(StringUtils.substringBetween(
							contentText, "name=\"cycleStartDate\" value=\"",
							"\""));
					qb.setEndDate(StringUtils.substringBetween(contentText,
							"name=\"cycleMap.endDate_" + this.date, "\" id")
							.substring(11));
					qb.setProdName(StringUtils.substringBetween(contentText,
							"name=\"customInfo.prodName\" value=\"", "\""));
					qb.setStartDate(StringUtils.substringBetween(contentText,
							"name=\"cycleMap.startDate_" + this.date, "\" id")
							.substring(11));
					qb.setSubsId(StringUtils.substringBetween(contentText,
							"name=\"customInfo.subsId\" value=\"", "\""));
					qb.setUnionacct(StringUtils.substringBetween(contentText,
							"name=\"cycleMap.unionacct_" + this.date, "\" id")
							.substring(11));
					String month = StringUtils.substringBetween(contentText,
							"name=\"cycleMap.acctId_" + this.date, "\"");
					pageid = Math.random() + "";
					httpost = new HttpPost(queryBillDetail + pageid);
					nvps = new ArrayList<NameValuePair>();
					nvps.add(new BasicNameValuePair("feeType", ""));
					nvps.add(new BasicNameValuePair("menuid", "queryBill"));
					nvps.add(new BasicNameValuePair("fieldErrFlag", ""));
					nvps.add(new BasicNameValuePair("contextPath", "/eMobile"));
					nvps.add(new BasicNameValuePair("customInfo.custName", qb
							.getCustName()));
					nvps.add(new BasicNameValuePair("customInfo.brandName", qb
							.getBrandName()));
					nvps.add(new BasicNameValuePair("customInfo.prodName", qb
							.getProdName()));
					nvps.add(new BasicNameValuePair("customInfo.subsId", qb
							.getSubsId()));
					nvps.add(new BasicNameValuePair("cycleMap.cycle_"
							+ this.date + month, qb.getCycle()));//
					nvps.add(new BasicNameValuePair("cycleMap.startDate_"
							+ this.date + month, qb.getStartDate()));
					nvps.add(new BasicNameValuePair("cycleMap.endDate_"
							+ this.date + month, qb.getEndDate()));
					nvps.add(new BasicNameValuePair("cycleMap.acctId_"
							+ this.date + month, qb.getAcctId()));
					nvps.add(new BasicNameValuePair("cycleMap.unionacct_"
							+ this.date + month, qb.getUnionacct()));
					nvps.add(new BasicNameValuePair("cycleStartDate", qb
							.getCycleStartDate()));
					nvps.add(new BasicNameValuePair("retMonth", date));
					nvps.add(new BasicNameValuePair("month", date));

					httpost.setEntity(new UrlEncodedFormEntity(nvps, UTF));
					response = httpclient.execute(httpost, localContext);
					entity = response.getEntity();
					if (entity != null) {
						contentText = EntityUtils.toString(entity, UTF);
						contentText = UnicodeToString(contentText);
						
						
						if (contentText.contains("账单未生成或不存在")) {

							String returnArr = queryAgain();
							if (returnArr.contains("话费余额")) {
								account.setBalance(StringUtils
										.substringBetween(returnArr,
												"[\"话费余额\",\"", "元\"]"));
							}
							if (returnArr.contains("协议款总余额")) {
								account.setXyBalance(StringUtils
										.substringBetween(returnArr,
												"[\"本月可用的协议款额度\",\"", "\"]"));
							}
							if (account.getBalance() != null) {
								account.setSuccess(Account.SUCCESS);
							} else {
								account.setSuccess(Account.FAIL);
								account.setMessage("查不到本月" + date
										+ "的账单,账单未生成或不存在!");
							}
							log.info("代理ip：" + px.getIp() + ":" + px.getPort()
									+ "手机卡:" + mobile + "密码:" + password
									+ "余额:" + account.getBalance() + "套餐外费用:"
									+ account.getChit() + "增值业务费"
									+ account.getValueAdded() + "代收费:"
									+ account.getCharge() + "本月费用合计:"
									+ account.getTotal() + "是否成功："
									+ account.getSuccess());
							return account;
						}
					
						
						String cardType = StringUtils.substringBetween(
								contentText, "短彩信费</td>", "&nbsp;&nbsp;</td>");
						cardType = cardType.replaceAll(
								"\t|\r|\n|<td style=\"text-align:right\">", "");
						account.setChit(cardType);
						
						if(contentText.contains("<STRONG>使用百分比</STRONG>")){
							cardType = StringUtils.substringBetween(
									contentText, "<STRONG>使用百分比</STRONG>", "%</td>");
							cardType+="</td>%";
							cardType = StringUtils.substringBetween(
									cardType, "<td align=\"left\" width=\"30%\">5元位置通套餐包</td>", "%");
							
							String[] array = StringUtils.substringsBetween(
									cardType, "<td align=\"left\">", "</td>");
							if(array!=null&&array.length>=2){
								account.setGprs(array[0]);
								account.setUsedgprs(array[1]);
							}
						}
						
						if(contentText.contains("<STRONG>使用百分比</STRONG>")&&account.getGprs()==null){
							cardType = StringUtils.substringBetween(
									contentText, "<STRONG>使用百分比</STRONG>", "%</td>");
							cardType+="</td>%";
							cardType = StringUtils.substringBetween(
									cardType, "<td align=\"left\" width=\"30%\">5元手机上网套餐包</td>", "%");
							
							String[] array = StringUtils.substringsBetween(
									cardType, "<td align=\"left\">", "</td>");
							if(array!=null&&array.length>=2){
								account.setGprs(array[0]);
								account.setUsedgprs(array[1]);
							}
						}
						
						
						cardType = StringUtils.substringBetween(contentText,
								"上网费</td>", "&nbsp;&nbsp;</td>");
						cardType = cardType.replaceAll(
								"\t|\r|\n|<td style=\"text-align:right\">", "");
						account.setNet(cardType);
						cardType = StringUtils.substringBetween(contentText,
								"增值业务费</STRONG></td>", "&nbsp;&nbsp;</td>");
						cardType = cardType
								.replaceAll(
										"\t|\r|\n|<td style=\"text-align:right;\">",
										"");
						account.setValueAdded(cardType);
						cardType = StringUtils.substringBetween(contentText,
								"代收费</STRONG></td>", "&nbsp;&nbsp;</td>");
						cardType = cardType
								.replaceAll(
										"\t|\r|\n|<td style=\"text-align:right;\">",
										"");
						account.setCharge(cardType);
						cardType = StringUtils.substringBetween(contentText,
								"本月费用合计</STRONG></td>", "&nbsp;&nbsp;</td>");
						cardType = cardType
								.replaceAll(
										"\t|\r|\n|<td style=\"text-align:right;\">",
										"");
						account.setTotal(cardType);
						cardType = StringUtils.substringBetween(contentText,
								"现金余额  </td>", "&nbsp;&nbsp;</td>");

						// 现金余额为null，重新获取余额
						if (cardType == null) {
							String returnArr = queryAgain();
							if (returnArr.contains("话费余额")) {
								account.setBalance(StringUtils
										.substringBetween(returnArr,
												"[\"话费余额\",\"", "元\"]"));
							}
							if (returnArr.contains("协议款总余额")) {
								account.setXyBalance(StringUtils
										.substringBetween(returnArr,
												"[\"本月可用的协议款额度\",\"", "\"]"));
							}

							if (account.getBalance() != null) {
								account.setSuccess(Account.SUCCESS);
							} else {
								account.setSuccess(Account.FAIL);
								account.setMessage("查不到本月" + date
										+ "的账单,账单未生成或不存在!");
							}
							
							

							log.info("代理ip：" + px.getIp() + ":" + px.getPort()
									+ "手机卡:" + mobile + "密码:" + password
									+ "余额:" + account.getBalance() + "套餐外费用:"
									+ account.getChit() + "增值业务费"
									+ account.getValueAdded() + "代收费:"
									+ account.getCharge() + "本月费用合计:"
									+ account.getTotal() + "是否成功："
									+ account.getSuccess());

							return account;

						} else {
							cardType = cardType
									.replaceAll(
											"\t|\r|\n|<td style=\"text-align:right;\">",
											"");
							account.setBalance(cardType);
							cardType = StringUtils.substringBetween(
									contentText, "协议款余额</td>",
									"&nbsp;&nbsp;</td>");
							if (StringUtils.isNotBlank(cardType)) {
								cardType = cardType
										.replaceAll(
												"\t|\r|\n|<td style=\"text-align:right;\">",
												"");
								account.setXyBalance(cardType);
							}
						}
						String[] st = StringUtils.substringsBetween(
								contentText, "<td", "</td>");
						if (st != null) {
							StringBuilder sb = new StringBuilder();
							String io = "";
							for (int i = 0; i < st.length; i++) {
								st[i] = st[i].replaceAll(
										"&nbsp;|\t|<.*?>|\n|\r", "")
										.replaceAll(".*?>|www.sd.10086.cn", "");
							}

							for (int i = 0; i < st.length; i++) {
								if (st[i].indexOf(".") > 0)
									sb.append(io + st[i] + " ");
								io = st[i].replaceAll("&nbsp;|\t|<.*?>", "")
										.replaceAll(".*?>|.*/元|.{20,100}", "");
							}
							account.setMessage(sb.toString());
						}
					}
				}
			} catch (Exception e) {
				log.info(mobile + "第" + accountCount + "次account失败"
						+ "message:" + e.toString() + ",Method="
						+ e.getStackTrace()[0].getMethodName() + ",Line="
						+ e.getStackTrace()[0].getLineNumber());
				Proxy np = proxyService.getProxy(mobilekey);
				return account(mobile, password, date, np);
			} finally {
				httpost.abort();
			}
			
			
			log.info("代理ip：" + px.getIp() + ":" + px.getPort() + "手机卡:"
					+ mobile + "密码:" + password + "余额:" + account.getBalance()
					+ "套餐外费用:" + account.getChit() + "增值业务费"
					+ account.getValueAdded() + "代收费:" + account.getCharge()
					+ "本月费用合计:" + account.getTotal()+ " 已使用流量:" + account.getUsedgprs() + " 总流量:" + account.getGprs()+ "是否成功："
					+ account.getSuccess());
			httpclient.getConnectionManager().shutdown();
			account.setSuccess(Account.SUCCESS);
			return account;
		} else {// login code!=0
			if (account.getCode() == 3 || account.getCode() == 7
					|| account.getCode() == 8) {
				Proxy np = proxyService.getProxy(mobilekey);
				return account(mobile, password, date, np);
			} else {
				log.info("代理ip：" + px.getIp() + ":" + px.getPort() + "手机卡:"
						+ mobile + "密码:" + password + "余额:"
						+ account.getBalance() + "套餐外费用:" + account.getChit()
						+ "增值业务费" + account.getValueAdded() + "代收费:"
						+ account.getCharge() + "本月费用合计:" + account.getTotal()
						+ " message：" + account.getMessage() + "是否成功："
						+ account.getSuccess());
				return account;
			}
		}

	}

	private Account login(String mobile, String password, Proxy px) {

		Account account = new Account(mobile, password);

		String randCode = getRandCode();
		HttpPost httpost = new HttpPost(shanDongLoginURL);
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();

		nvps.add(new BasicNameValuePair("submitMode", "2"));
		nvps.add(new BasicNameValuePair("ErrorUrl", "../mainLogon.do"));
		nvps.add(new BasicNameValuePair("ReturnURL",
				"www.sd.10086.cn/eMobile/jsp/common/prior.jsp"));
		nvps.add(new BasicNameValuePair("FieldID", "1"));
		nvps.add(new BasicNameValuePair("entrance", "IndexBrief"));
		nvps.add(new BasicNameValuePair("continueUrl", "null"));
		nvps.add(new BasicNameValuePair("mobileNum", mobile));
		nvps.add(new BasicNameValuePair("logonMode", "1"));
		nvps.add(new BasicNameValuePair("servicePWD", password));
		nvps.add(new BasicNameValuePair("randCode", randCode));
		nvps.add(new BasicNameValuePair("smsRandomCode", ""));
		nvps.add(new BasicNameValuePair("loginCheckBox", "on"));
		nvps.add(new BasicNameValuePair("account", ""));
		nvps.add(new BasicNameValuePair("accountPWD", ""));
		try {
			httpost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
			this.response = this.httpclient.execute(httpost, this.localContext);
			this.entity = this.response.getEntity();
			if (this.entity != null) {
				String rs = EntityUtils.toString(this.entity, "utf-8");
				if ("0".equals(rs)) {
					account.setCode(0);
					account.setSuccess(Account.SUCCESS);

					// 获取各种cookie

					// 首页
					// String aa = co.getText("首页",httpclient,
					// localContext,"http://www.sd.10086.cn/eMobile/jsp/common/prior.jsp");
					String responseText = null;
					// cookieServletURL
					responseText = co.getText("cookieServlet:", httpclient,
							localContext, cookieServletURL);
					responseText = StringUtils.substringBetween(responseText,
							"var a='", "';");

					// sso1
					String new_loginAttritdtURL = loginAttritdUrl
							+ responseText;
					responseText = co.getText("sso:", httpclient, localContext,
							new_loginAttritdtURL);
					// jsessionid
					// responseText = co
					// .getText("jsessionid:", httpclient,
					// localContext,"https://sd.ac.10086.cn/emall/eMobile/emobileHeader.action");

					if (responseText.contains("您是第一次在网站登录")) {
						// 首次登入
						try {
							firstLogin();
						} catch (UnsupportedEncodingException e) {
							log.info(mobile + "首次登入失败:" + e.toString()
									+ ",Method="
									+ e.getStackTrace()[0].getMethodName()
									+ ",Line="
									+ e.getStackTrace()[0].getLineNumber());
							firstLogin();
						}
					}else if(responseText.contains("无法定位用户")){
						account.setCode(5);
						account.setSuccess(Account.FAIL);
						account.setMessage("无法定位用户");
						return account;
					}
					
					return account;
				} else if (rs.contains("验证码错误")) {
					account.setCode(3);
					account.setSuccess(Account.FAIL);
					account.setMessage("验证码错误");
					return account;
				} else {
					// 登入失败，直接返回
					account.setCode(2);
					account.setSuccess(Account.FAIL);
					account.setMessage(rs);
					return account;
				}

			} else {// entity为null，尝试重新登入
					// 登入失败，直接返回
				account.setCode(2);
				account.setSuccess(Account.FAIL);
				account.setMessage("entity为null登入失败,mobile:" + mobile);
				return account;
			}

		} catch (SocketTimeoutException e) {
			account.setCode(7);
			log.info("mobile:" + mobile + " login请求超时!" + e.toString()
					+ ",Method=" + e.getStackTrace()[0].getMethodName()
					+ ",Line=" + e.getStackTrace()[0].getLineNumber());
			account.setSuccess(Account.FAIL);
			account.setMessage("login请求超时!");
			return account;
		} catch (Exception e) {
			account.setCode(8);
			account.setSuccess(Account.FAIL);
			account.setMessage("由于网络或其他原因login失败！");
			log.info("mobile login 由于网络或其他原因mobile:" + mobile + ","
					+ e.toString() + ",Method="
					+ e.getStackTrace()[0].getMethodName() + ",Line="
					+ e.getStackTrace()[0].getLineNumber());
			return account;

		} finally {
			httpost.abort();
		}

	}

	public String firstLogin() throws UnsupportedEncodingException {
		HttpPost httpost = new HttpPost(firstLogin);

		Header accept = new BasicHeader("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		Header lan = new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8");
		Header headerconn = new BasicHeader("Connection", "keep-alive");
		Header caco = new BasicHeader("Cache-Control", "max-age=0");
		Header origin = new BasicHeader("Origin", "http://www.sd.10086.cn");
		Header headerref = new BasicHeader("Referer",
				"http://www.sd.10086.cn/eMobile/firstLogin.action?menuid=");
		Header headerhost = new BasicHeader("Host", "www.sd.10086.cn");
		Header contype = new BasicHeader("Content-Type",
				"application/x-www-form-urlencoded");

		httpost.addHeader(contype);
		httpost.addHeader(headerhost);
		httpost.addHeader(origin);
		httpost.addHeader(headerconn);
		httpost.addHeader(headerref);
		httpost.addHeader(accept);
		httpost.addHeader(caco);
		httpost.addHeader(lan);

		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		nvps.add(new BasicNameValuePair("menuid", ""));
		nvps.add(new BasicNameValuePair("fieldErrFlag", ""));
		nvps.add(new BasicNameValuePair("contextPath", "/eMobile"));
		httpost.setEntity(new UrlEncodedFormEntity(nvps, UTF));

		String text = "";
		HttpResponse response = null;
		try {
			response = httpclient.execute(httpost, localContext);
			HttpEntity entity = response.getEntity();

			if (entity != null) {
				text = EntityUtils.toString(entity, UTF);
			}

		} catch (Exception e) {
			text = "";
		} finally {
			httpost.abort();
		}
		return text;
	}

	public int onlyaccountCount = 0;
	public Account onlyAccount(String mobile, String password, String date, Proxy px) {
		onlyaccountCount++;
		if (onlyaccountCount >=4) {
			Account account = new Account(mobile, password);
			log.info(mobile + ":第" + --onlyaccountCount + "次查询余额失败！");
			account.setCode(3333);
			account.setSuccess(Account.FAIL);
			account.setMessage("第" + --onlyaccountCount + "次查询余额失败！");
			log.info("第" + --onlyaccountCount + "次查询余额失败！"+"代理ip：" + px.getIp() + ":" + px.getPort()+"手机卡:" + mobile + "密码:" + password + "余额:"
					+ account.getBalance() + " message：" + account.getMessage()+"是否成功："+account.getSuccess());
			return account;
		}
		
		this.date = date;
		if (mobile.length() != 11) {
			return new Account(mobile, password, 11, Account.FAIL, "手机号码位数不正确");
		}
		if (password.length() != 6) {
			return new Account(mobile, password, 11, Account.FAIL, "服务密码位数不正确");
		}
		// 设置代理ip
		HttpParams httpParams = new BasicHttpParams();
//		HttpHost proxy = new HttpHost(px.getIp(), px.getPort(), "http");

		// 设置超时时间
		HttpConnectionParams.setConnectionTimeout(httpParams, REQUEST_TIMEOUT);
		HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
		// 设置代理
//		ConnRouteParams.setDefaultProxy(httpParams, proxy);
//		log.info("代理ip：" + px.getIp() + ":" + px.getPort() + ",mobile:"
//				+ mobile);

		httpclient = new DefaultHttpClient();
		httpclient = (DefaultHttpClient) wrapClient(httpclient);
		httpclient.setParams(httpParams);
		cookieStore = new BasicCookieStore();
		localContext = new BasicHttpContext();

		httpclient.getParams().setParameter(
				ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
		// 设置cookie的兼容性，这一行必须要加，否则服务器无法获取登陆状态
		HttpClientParams.setCookiePolicy(httpclient.getParams(),
				CookiePolicy.BROWSER_COMPATIBILITY);
		localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
		Cookie ccm = new BasicClientCookie("CmProvid", "sd");
		cookieStore.addCookie(ccm);
		Account account = login(mobile, password, px);
		
		if (account.getCode() == 0) {
			try {
					String returnArr = queryAgain();
					if (returnArr.contains("话费余额")) {
						account.setBalance(StringUtils
								.substringBetween(returnArr,
										"[\"话费余额\",\"", "\"]"));
						log.info("代理ip：" + px.getIp() + ":" + px.getPort()+"手机卡:" + mobile + "密码:" + password + "余额:"
								+ account.getBalance() + " message：" + account.getMessage()+"是否成功："+account.getSuccess());
						account.setSuccess(Account.SUCCESS);
						httpclient.getConnectionManager().shutdown();
						return account;
					}else{
						httpclient.getConnectionManager().shutdown();
						Proxy np = proxyService.getProxy(mobilekey);
						return onlyAccount(mobile, password, date, np);
					}
						
			} catch (Exception e) {
				httpclient.getConnectionManager().shutdown();
				if(account.getBalance()!=null){
					return account;
				}else{
					log.info(mobile + "第" + onlyaccountCount + "次account失败"
							+"message:"+e.toString()+",Method="+e.getStackTrace()[0].getMethodName()+",Line="+ e.getStackTrace()[0].getLineNumber());
					Proxy np = proxyService.getProxy(mobilekey);
					httpclient.getConnectionManager().shutdown();
					return onlyAccount(mobile, password, date, np);
				}
			}
		} else {// login code!=0
			if (account.getCode() == 3 || account.getCode() == 7
					|| account.getCode() == 8) {
				httpclient.getConnectionManager().shutdown();
				Proxy np = proxyService.getProxy(mobilekey);
				return onlyAccount(mobile, password, date, np);
			} else {
				log.info("代理ip：" + px.getIp() + ":" + px.getPort() + "手机卡:"
						+ mobile + "密码:" + password + "余额:"
						+ account.getBalance() + " message：" + account.getMessage()+  "是否成功："
						+ account.getSuccess());
				return account;
			}
		}
	}

	public String queryAgain() throws UnsupportedEncodingException {
		HttpPost httpost = new HttpPost(qryBalanceResult + Math.random());

		Header accept = new BasicHeader("Accept", "*/*");
		Header lan = new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8");
		Header xr = new BasicHeader("X-Requested-With", "XMLHttpRequest");
		Header headerconn = new BasicHeader("Connection", "keep-alive");
		Header origin = new BasicHeader("Origin", "http://www.sd.10086.cn");
		Header headerref = new BasicHeader("Referer",
				"http://www.sd.10086.cn/eMobile/qryBalance.action?menuid=qryBalance&pageId="
						+ Math.random());
		Header headerhost = new BasicHeader("Host", "www.sd.10086.cn");

		httpost.addHeader(xr);
		httpost.addHeader(headerhost);
		httpost.addHeader(origin);
		httpost.addHeader(headerconn);
		httpost.addHeader(headerref);
		httpost.addHeader(accept);
		httpost.addHeader(lan);

		String text = "";
		HttpResponse response = null;
		try {
			response = httpclient.execute(httpost, localContext);
			HttpEntity entity = response.getEntity();

			if (entity != null) {
				text = EntityUtils.toString(entity, UTF);
			}

		} catch (Exception e) {
			text = "";
		} finally {
			httpost.abort();
		}
		return text;
	}

	int i = 0;

	private String getRandCode() {
		i++;
		if (i > 5) {
			i = 0;
			return "";
		}
		// 验证码
		String randCode = "";
		try {
			randCode = co.getResponse(httpclient, localContext, randCodeURL,
					new ClientOperate.RespProcess() {
						public String doProcess(HttpResponse response) {
							String randCode = "";
							entity = response.getEntity();
							if (entity != null) {
								InputStream instream = null;
								try {
									instream = entity.getContent();
									BufferedImage image = ImageIO
											.read(instream);
									if (image == null) {
										randCode = "";
									} else {
										randCode = authCodeDiscern.discern(
												image, false);
									}
								} catch (IllegalStateException e) {
									// e.printStackTrace();
								} catch (IOException e) {
									// e.printStackTrace();
								}
							}
							return randCode;
						}
					});
		} catch (ClientProtocolException e) {
			randCode = "";
		} catch (IOException e) {
			randCode = "";
		}
		if (StringUtils.isNotBlank(randCode)) {
			i = 0;
			return randCode;
		} else {
			return getRandCode();
		}
	}

	@Override
	public boolean check(String city) {
		return "sd".equals(city);
	}

	private static String UnicodeToString(String str) {
		Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
		Matcher matcher = pattern.matcher(str);
		char ch;
		while (matcher.find()) {
			ch = (char) Integer.parseInt(matcher.group(2), 16);
			str = str.replace(matcher.group(1), ch + "");
		}
		return str;
	}

	/**
	 * 获取可信任https链接，以避免不受信任证书出现peer not authenticated异常
	 * 
	 * @param base
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static DefaultHttpClient wrapClient(HttpClient base) {
		try {
			SSLContext ctx = SSLContext.getInstance("TLS");
			X509TrustManager tm = new X509TrustManager() {
				public void checkClientTrusted(X509Certificate[] xcs,
						String string) {
				}

				public void checkServerTrusted(X509Certificate[] xcs,
						String string) {
				}

				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			};
			ctx.init(null, new TrustManager[] { tm }, null);
			SSLSocketFactory ssf = new SSLSocketFactory(ctx);
			ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			ClientConnectionManager ccm = base.getConnectionManager();
			SchemeRegistry sr = ccm.getSchemeRegistry();
			sr.register(new Scheme("https", ssf, 443));
			return new DefaultHttpClient(ccm, base.getParams());
		} catch (Exception e) {
			log.info("client创建失败！message：" + e.toString() + ",Method="
					+ e.getStackTrace()[0].getMethodName() + ",Line="
					+ e.getStackTrace()[0].getLineNumber());
			// ex.printStackTrace();
			return null;
		}
	}
	
	
	public String GPRS() throws UnsupportedEncodingException {
		HttpGet httpget = new HttpGet(gprs+Math.random());

		Header accept = new BasicHeader("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		Header lan = new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8");
		Header headerconn = new BasicHeader("Connection", "keep-alive");
		Header headerhost = new BasicHeader("Host", "www.sd.10086.cn");
		Header contype = new BasicHeader("Content-Type",
				"application/x-www-form-urlencoded");

		httpget.addHeader(contype);
		httpget.addHeader(headerhost);
		httpget.addHeader(headerconn);
		httpget.addHeader(accept);
		httpget.addHeader(lan);


		String text = "";
		HttpResponse response = null;
		try {
			response = httpclient.execute(httpget, localContext);
			HttpEntity entity = response.getEntity();

			if (entity != null) {
				text = EntityUtils.toString(entity, UTF);
			}

		} catch (Exception e) {
			text = "";
		} finally {
			httpget.abort();
		}
		return text;
	}
//	try {
//		String liuliang=GPRS();
//		//"returnArr":[["5元位置通套餐包","GPRS","30.00","30.00","M","","0","20140901","20140930"]]}
//		
//		liuliang = StringUtils.substringBetween(liuliang,
//				"returnArr\":[[\"5元位置通套餐包\",\"GPRS\",\"", "\",\"M");
//		String[] arr=liuliang.split("\",\"");
//		for (int i = 0; i < arr.length; i++) {
//			System.out.println(arr[i]);
//		}
//		
//	} catch (UnsupportedEncodingException e) {
//		// TODO Auto-generated catch block
//		e.printStackTrace();
//	}


}
